﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Web;
using System.Data.Services; 
using Microsoft.WindowsAzure.StorageClient;
using Microsoft.WindowsAzure;
using Microsoft.WindowsAzure.ServiceRuntime;

namespace BreadWebRole
{
    /// <summary> 
    /// This is the WCF Data Service object context. 
    /// Do not confuse it with DailyBreadTableStorageContext (the table storage context). 
    /// Table storage does not use EDM or LINQ to SQL. 
    /// So we must create a custom object context that implements IUpdatable. 
    /// This sample only demonstrates simple CRUD operations. So not all methods are implemented. 
    /// </summary> 
    public class DailyBreadDataServiceContext : IUpdatable
    {
        private DailyBreadTableStorageContext _ctx = new DailyBreadTableStorageContext();


        public IQueryable<DailyBreadComments> Comments
        {
            get 
            { 
                return this._ctx.Comments; 
            }
        }

        public IQueryable<DailyBreadFavorites> Favorites
        {
            get
            {
                return this._ctx.Favorites;
            }
        }

        public IQueryable<DailyBreadLogs> Logs
        {
            get
            {
                return this._ctx.Logs;
            }
        }

        public void AddReferenceToCollection(object targetResource, string propertyName, object resourceToBeAdded)
        {
            throw new NotImplementedException();
        }

        public void ClearChanges()
        {
            //throw new NotImplementedException();
            
            return;
        }

        public object CreateResource(string containerName, string fullTypeName) 
        {
            if (fullTypeName == typeof(DailyBreadComments).ToString())
            {
                DailyBreadComments entity = new DailyBreadComments();
                // Add the entity to table context. 
                this._ctx.AddObject("comments", entity);
                return entity;
            }
            else if (fullTypeName == typeof(DailyBreadFavorites).ToString())
            {
                DailyBreadFavorites entity = new DailyBreadFavorites();
                // Add the entity to table context. 
                this._ctx.AddObject("favorites", entity);
                return entity;
            }
            else if (fullTypeName == typeof(DailyBreadLogs).ToString())
            {
                DailyBreadLogs entity = new DailyBreadLogs();
                // Add the entity to table context. 
                this._ctx.AddObject("logs", entity);
                return entity;
            }
            throw new NotSupportedException(string.Format("{0} not found", fullTypeName)); 

        }

        /// <summary> 
        /// Delete the person entity from table storage. 
        /// </summary> 
        public void DeleteResource(object targetResource)
        {
            if (targetResource.ToString() == typeof(DailyBreadComments).ToString())
            {
                throw new NotSupportedException();
                //DailyBreadComments comment = targetResource as DailyBreadComments;
                //if (comment == null)
                //{
                //    throw new DataServiceException(400, "Invalid object. Object must be a Person");
                //}
                //this._ctx.DeleteObject(comment);
                //this._ctx.SaveChanges();
            }
            else if (targetResource.ToString() == typeof(DailyBreadFavorites).ToString())
            {
                DailyBreadFavorites fav = targetResource as DailyBreadFavorites;
                if (fav == null)
                {
                    throw new DataServiceException(400, "Invalid object. Object must be a Favorite");
                }
                this._ctx.DeleteObject(fav);
                this._ctx.SaveChanges();
            }
            else if (targetResource.ToString() == typeof(DailyBreadLogs).ToString())
            {
                DailyBreadLogs log = targetResource as DailyBreadLogs;
                if (log == null)
                {
                    throw new DataServiceException(400, "Invalid object. Object must be a Log");
                }
                this._ctx.DeleteObject(log);
                this._ctx.SaveChanges();
            }
            else
            {
                throw new NotSupportedException();
            }
        }

        /// <summary> 
        /// GetResource is invoked before updating and deletion. 
        /// </summary> 
        public object GetResource(IQueryable query, string fullTypeName)
        {
            if (query.ElementType.ToString() == typeof(DailyBreadComments).ToString())
            {
                IQueryable<DailyBreadComments> tableQuery = query as IQueryable<DailyBreadComments>;
                if (tableQuery == null)
                {
                    throw new DataServiceException(400, "Invalid query.");
                }
                return tableQuery.First();
            }
            else if (query.ElementType.ToString() == typeof(DailyBreadFavorites).ToString())
            {
                IQueryable<DailyBreadFavorites> tableQuery = query as IQueryable<DailyBreadFavorites>;
                if (tableQuery == null)
                {
                    throw new DataServiceException(400, "Invalid query.");
                }
                return tableQuery.First();
            }
            else if (query.ElementType.ToString() == typeof(DailyBreadLogs).ToString())
            {
                IQueryable<DailyBreadLogs> tableQuery = query as IQueryable<DailyBreadLogs>;
                if (tableQuery == null)
                {
                    throw new DataServiceException(400, "Invalid query.");
                }
                return tableQuery.First();
            }
            throw new NotSupportedException(string.Format("{0} not found", fullTypeName)); 
        }

        public object GetValue(object targetResource, string propertyName)
        {
            throw new NotImplementedException();
        }

        public void RemoveReferenceFromCollection(object targetResource, string propertyName, object resourceToBeRemoved)
        {
            throw new NotImplementedException();
        }

        public object ResetResource(object resource)
        {
            throw new NotImplementedException();
        }

        public object ResolveResource(object resource)
        {
            return resource;
        }

        public void SaveChanges()
        {
            this._ctx.SaveChanges();
        }

        public void SetReference(object targetResource, string propertyName, object propertyValue)
        {
            throw new NotImplementedException();
        }

        /// <summary> 
        /// SetValue is invoked before updating. 
        /// </summary> 
        public void SetValue(object targetResource, string propertyName, object propertyValue)
        {
            // The Partition/RowKey should not be modified. 
            //if (propertyValue != null && propertyName != "PartitionKey" && propertyName != "RowKey")
            if (propertyValue != null)
            {
                if (targetResource.ToString() == typeof(DailyBreadComments).ToString())
                {
                    DailyBreadComments comment = (DailyBreadComments)targetResource;
                    typeof(DailyBreadComments).GetProperty(propertyName).SetValue(comment, propertyValue, null);
                    this._ctx.UpdateObject(comment);
                }
                else if (targetResource.ToString() == typeof(DailyBreadFavorites).ToString())
                {
                    DailyBreadFavorites fav = (DailyBreadFavorites)targetResource;
                    typeof(DailyBreadFavorites).GetProperty(propertyName).SetValue(fav, propertyValue, null);
                    this._ctx.UpdateObject(fav);
                }
                else if (targetResource.ToString() == typeof(DailyBreadLogs).ToString())
                {
                    DailyBreadLogs log = (DailyBreadLogs)targetResource;
                    typeof(DailyBreadLogs).GetProperty(propertyName).SetValue(log, propertyValue, null);
                    this._ctx.UpdateObject(log);
                }
                else
                {
                    throw new NotSupportedException();
                }
            }
        }
    } 

}